package com.shareach.dao.mongo.impl;

import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.springframework.data.domain.Page;
import org.springframework.data.mongodb.core.mapreduce.GroupBy;
import org.springframework.data.mongodb.core.mapreduce.GroupByResults;
import org.springframework.data.mongodb.core.mapreduce.MapReduceResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Order;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Component;

import com.shareach.common.BaseQueryOrder;
import com.shareach.common.CollectionNames;
import com.shareach.dao.MongoDBBasicDao;
import com.shareach.dao.mongo.BaseCityDao;
import com.shareach.domain.BaseCityDomain;

@Component
public class BaseCityDaoImpl extends MongoDBBasicDao<BaseCityDomain> implements BaseCityDao {

	@Override
	public void insert(BaseCityDomain domain) {
		if (null == domain.getCreatTime()) {
			domain.setCreatTime(new Date());
		}
		super.save(domain);
	}

	@Override
	public <T> void delete(Query query, Class<T> clas) {
		mongoTemplate.remove(query, clas);
	}

	@Override
	public void update(Criteria criteria, Update update) {
		super.update(criteria, update, BaseCityDomain.class);
	}

	@Override
	public List<BaseCityDomain> findList(Criteria criteria) {
		return super.findList(criteria, BaseCityDomain.class);
	}

	@Override
	public List<BaseCityDomain> findList(Query query) {
		return super.findList(query, BaseCityDomain.class);
	}

	@Override
	public BaseCityDomain findOne(Query query) {
		return super.findOne(query, BaseCityDomain.class);
	}

	@Override
	public List<BaseCityDomain> getLastNumberByCondition(LinkedHashMap<String, String> conditionArgs) {
		Query query = new Query();

		query.sort().on("access_date", Order.DESCENDING);

		for (Map.Entry<String, String> singleArg : conditionArgs.entrySet()) {
			query.addCriteria(new Criteria(singleArg.getKey()).is(singleArg.getValue()));
		}
		return super.findList(query, BaseCityDomain.class);
	}

	@Override
	public <T> MapReduceResults<T> groupMapReduce(Query query, String map, String reduce, Class<T> clas) {
		return mongoTemplate.mapReduce(query, CollectionNames.BASECITY, map, reduce, clas);
	}

	@Override
	public <T> GroupByResults<T> group(Criteria criteria, String key, String map, String reduce, Class<T> clas) {
		return mongoTemplate.group(criteria, CollectionNames.BASECITY, GroupBy.key(key).initialDocument(map)
				.reduceFunction(reduce), clas);
	}

	@Override
	public <T> GroupByResults<T> groups(Criteria criteria, String map, String reduce, Class<T> clas, String... key) {
		return mongoTemplate.group(criteria, CollectionNames.BASECITY, GroupBy.key(key).initialDocument(map)
				.reduceFunction(reduce), clas);
	}

	@Override
	public List<BaseCityDomain> findAll() {
		return mongoTemplate.findAll(BaseCityDomain.class);
	}

	@Override
	public Page<BaseCityDomain> getPageResult(Query query, BaseQueryOrder order) {
		return getPageResult(query, order, BaseCityDomain.class);
	}

	@Override
	public void update(Query query, Update update) {
		super.update(query, update, BaseCityDomain.class);
	}
}
